package jdbc_test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/*
    JDBC事务控制：
        1.事务：一个包含多个步骤的业务操作。如果这个业务操作被事务管理，则着多个步骤要么同时成功，要么同时失败
        2.操作：使用Connection对象来管理事务
              开启事务：void setAutoCommit(boolean autoCommit) 将此连接的自动提交模式设置为给定状态。 调用该方法将参数设置为false，即开启事务（关闭自动提交，因此转为手动提交）
                   在获取数据库对象之后开启事务
              提交事务：void commit() 使自上次提交/回滚以来所做的所有更改都将永久性，并释放此 Connection对象当前持有的任何数据库锁。
                   当所有jdbc执行完处理结果之后提交事务
              回滚事务：void rollback() 撤消在当前事务中所做的所有更改（撤销所有的SQL语句），并释放此 Connection对象当前持有的任何数据库锁。
                   在catch中回滚事务,因为一旦出现异常，就会进入到异常处理，而且是对所有的更改进行回滚，所以要抛一个大的异常Exception
 */
public class PracticeMain2 {
    public static void main(String[] args) {
        //1.导入驱动jar包
        Connection connection = null;
        Statement statement = null;
        try {
            //2.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");//将字节码文件加载到内存中

            //3.获取数据库连接对象
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/uuuu?serverTimezone=UTC", "root", "root");
            //开启事务
            connection.setAutoCommit(false);//参数为false来开启事务

            // 4.定义sql语句
            String sql = "update student set aaa = 60 where bbb = 'wang'";
            // 5.获取执行sql的对象
            statement = connection.createStatement();
            // 6.执行sql

            //如果在运行过程中出现异常
            int i = 10/0;

            long l = statement.executeLargeUpdate(sql);
            //7.处理结果
            System.out.println(l);

            //提交事务
            connection.commit();

        }catch (Exception e) {
            //回滚事务,有异常抛出
            try {
                if(connection != null){//判断数据库是否连接
                    connection.rollback();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            //8.释放资源
            /*
                1.提升statement，connection作用域
                2.避免空指针异常，若第3步执行出错，后面的代码就执行不到
             */
            if(statement != null){
                try {
                    statement.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(connection != null){
                try {
                    connection.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

        }
    }

}
